package sms

import (
	"errors"
	"fmt"
	"math/rand"
	"sync"
	"time"

	"pbj-server/config"
	"pbj-server/pkg/logger"
	// "pbj-server/pkg/redis"  // 暂时禁用Redis

	"github.com/aliyun/alibaba-cloud-sdk-go/services/dysmsapi"
	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
	tencenterrors "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
	sms "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms/v20210111"
)

var (
	aliyunClient  *dysmsapi.Client
	tencentClient *sms.Client
	cfg           *config.Config
	
	// 内存验证码存储（替代Redis）
	codeStore = make(map[string]codeInfo)
	codeMutex sync.RWMutex
)

// codeInfo 验证码信息
type codeInfo struct {
	Code      string    // 验证码
	ExpireAt  time.Time // 过期时间
}

// SMSProvider SMS服务提供商接口
type SMSProvider interface {
	SendSMS(phone, code string) error
}

// AliyunSMSProvider 阿里云短信服务
type AliyunSMSProvider struct{}

// TencentSMSProvider 腾讯云短信服务
type TencentSMSProvider struct{}

// Init 初始化SMS服务
func Init() error {
	cfg = config.GetConfig()
	
	switch cfg.SMS.Provider {
	case "aliyun":
		return initAliyunSMS()
	case "tencent":
		return initTencentSMS()
	default:
		return fmt.Errorf("不支持的SMS提供商: %s", cfg.SMS.Provider)
	}
}

// initAliyunSMS 初始化阿里云短信服务
func initAliyunSMS() error {
	var err error
	aliyunClient, err = dysmsapi.NewClientWithAccessKey(
		cfg.SMS.Aliyun.RegionID,
		cfg.SMS.Aliyun.AccessKeyID,
		cfg.SMS.Aliyun.AccessKeySecret,
	)
	if err != nil {
		return fmt.Errorf("初始化阿里云短信客户端失败: %v", err)
	}
	
	logger.Info("阿里云短信服务初始化成功")
	return nil
}

// initTencentSMS 初始化腾讯云短信服务
func initTencentSMS() error {
	credential := common.NewCredential(
		cfg.SMS.Tencent.SecretID,
		cfg.SMS.Tencent.SecretKey,
	)
	
	cpf := profile.NewClientProfile()
	cpf.HttpProfile.Endpoint = "sms.tencentcloudapi.com"
	
	var err error
	tencentClient, err = sms.NewClient(credential, cfg.SMS.Tencent.Region, cpf)
	if err != nil {
		return fmt.Errorf("初始化腾讯云短信客户端失败: %v", err)
	}
	
	logger.Info("腾讯云短信服务初始化成功")
	return nil
}

// SendSMS 发送短信验证码
func SendSMS(phone, code string) error {
	switch cfg.SMS.Provider {
	case "aliyun":
		return sendAliyunSMS(phone, code)
	case "tencent":
		return sendTencentSMS(phone, code)
	default:
		return fmt.Errorf("不支持的SMS提供商: %s", cfg.SMS.Provider)
	}
}

// sendAliyunSMS 发送阿里云短信
func sendAliyunSMS(phone, code string) error {
	request := dysmsapi.CreateSendSmsRequest()
	request.Scheme = "https"
	request.PhoneNumbers = phone
	request.SignName = cfg.SMS.Aliyun.SignName
	request.TemplateCode = cfg.SMS.Aliyun.TemplateCode
	request.TemplateParam = fmt.Sprintf(`{"code":"%s"}`, code)
	
	response, err := aliyunClient.SendSms(request)
	if err != nil {
		return fmt.Errorf("发送阿里云短信失败: %v", err)
	}
	
	if response.Code != "OK" {
		return fmt.Errorf("阿里云短信发送失败: %s", response.Message)
	}
	
	logger.Infof("阿里云短信发送成功，手机号: %s, 验证码: %s", phone, code)
	return nil
}

// sendTencentSMS 发送腾讯云短信
func sendTencentSMS(phone, code string) error {
	request := sms.NewSendSmsRequest()
	request.SmsSdkAppId = common.StringPtr(cfg.SMS.Tencent.AppID)
	request.SignName = common.StringPtr(cfg.SMS.Tencent.SignName)
	request.TemplateId = common.StringPtr(cfg.SMS.Tencent.TemplateID)
	request.TemplateParamSet = common.StringPtrs([]string{code})
	request.PhoneNumberSet = common.StringPtrs([]string{fmt.Sprintf("+86%s", phone)})
	
	response, err := tencentClient.SendSms(request)
	if err != nil {
		var sdkError *tencenterrors.TencentCloudSDKError
		if errors.As(err, &sdkError) {
			return fmt.Errorf("发送腾讯云短信失败: %s", sdkError.Message)
		}
		return fmt.Errorf("发送腾讯云短信失败: %v", err)
	}
	
	if *response.Response.SendStatusSet[0].Code != "Ok" {
		return fmt.Errorf("腾讯云短信发送失败: %s", *response.Response.SendStatusSet[0].Message)
	}
	
	logger.Infof("腾讯云短信发送成功，手机号: %s, 验证码: %s", phone, code)
	return nil
}

// GenerateCode 生成验证码
func GenerateCode() string {
	rand.Seed(time.Now().UnixNano())
	code := rand.Intn(900000) + 100000 // 生成6位数字验证码
	return fmt.Sprintf("%06d", code)
}

// SendVerificationCode 发送验证码并存储到内存
func SendVerificationCode(phone string) (string, error) {
	// 生成验证码
	code := GenerateCode()
	
	// 发送短信
	if err := SendSMS(phone, code); err != nil {
		return "", err
	}
	
	// 将验证码存储到内存，设置5分钟过期
	key := fmt.Sprintf("sms:code:%s", phone)
	codeMutex.Lock()
	codeStore[key] = codeInfo{
		Code:     code,
		ExpireAt: time.Now().Add(5 * time.Minute),
	}
	codeMutex.Unlock()
	
	logger.Infof("验证码已存储到内存，手机号: %s, 验证码: %s", phone, code)
	return code, nil
}

// VerifyCode 验证验证码
func VerifyCode(phone, code string) (bool, error) {
	key := fmt.Sprintf("sms:code:%s", phone)
	
	// 从内存获取验证码
	codeMutex.RLock()
	info, exists := codeStore[key]
	codeMutex.RUnlock()
	
	// 验证码不存在
	if !exists {
		return false, fmt.Errorf("验证码已过期或不存在")
	}
	
	// 检查是否过期
	if time.Now().After(info.ExpireAt) {
		// 删除过期的验证码
		codeMutex.Lock()
		delete(codeStore, key)
		codeMutex.Unlock()
		return false, fmt.Errorf("验证码已过期")
	}
	
	// 验证码匹配
	if info.Code == code {
		// 验证成功后删除验证码
		codeMutex.Lock()
		delete(codeStore, key)
		codeMutex.Unlock()
		return true, nil
	}
	
	return false, fmt.Errorf("验证码错误")
}

// GetProvider 获取当前SMS提供商
func GetProvider() string {
	return cfg.SMS.Provider
}

// IsPhoneValid 验证手机号格式
func IsPhoneValid(phone string) bool {
	// 简单的手机号验证，可以根据需要扩展
	if len(phone) != 11 {
		return false
	}
	
	// 检查是否以1开头
	if phone[0] != '1' {
		return false
	}
	
	// 检查第二位是否为3-9
	if phone[1] < '3' || phone[1] > '9' {
		return false
	}
	
	return true
} 